<?php
/**
 * @version 1.5.9
 * +add Get Controller
 * +add addArgument,newArgument
 * +add newController
 */
class URI
{
	const DS = '.';//delimiter for Modules
	const ESCAPE_DS = '@';
	
	private $_host;
	private $_path;
	private $_query = array();
	private $_string = array(
		'host' => '',
		'path' => '',
		'query' => null,
		'fragment' => ''
	);
	public function __construct($host = null)
	{
		$this->_string['host'] = $host;
	}
	public function Host($host)
	{
		$this->_string['host'] = $host;
		return $this;
	}
	public function Path($path)
	{
		$this->_string['path'] = $path;
		return $this;
	}
	public function Query($query,$list = array())
	{
		if(is_array($list))
		{
			$this->_query = array_merge($query,$list);
		}
		else
		{
			$tmp = func_get_args();
			$query = array_shift($tmp);
			
			$list = array_combine($tmp,array_fill(0,count($tmp) ,null));
			$this->_query = array_merge($query,$list);
		}
		return $this;
	}
	public function setArgument($name,$value)
	{
		$this->_query[$name] = $value;
		return $this;
	}
	public function setRawController($name_var,$n0)
	{
		$tmp = func_get_args();
		if ( count($tmp) > 1 )
		{
			$name_var = array_shift($tmp);
			$this->_query[$name_var] = implode (self::DS , $tmp);
		}
		else
		{
			$this->_query[$name_var] = $n0;
		}
		return $this;
	}
	public function sC($name_var,$n0)
	{
		$tmp = func_get_args();
		if ( count($tmp) > 1 )
		{
			$this->_query[$name_var] = '';
			$ds = '';
			$name_var = array_shift($tmp);
			$traslate = array(self::DS => self::ESCAPE_DS . self::DS);
			foreach($tmp as $p)
			{
				$this->_query[$name_var] .= $ds . strtr($p,$traslate);
				$ds = self::DS;
			}
		}
		else
		{
			$this->_query[$name_var] = $n0;
		}
		return $this;
	}
	public function sRC($name_var,$n0)
	{
		$tmp = func_get_args();
		if ( count($tmp) > 1 )
		{
			$name_var = array_shift($tmp);
			$this->_query[$name_var] = implode (self::DS , $tmp);
		}
		else
		{
			$this->_query[$name_var] = $n0;
		}
		return $this;
	}
	public function setController($name_var,$n0)
	{
		$tmp = func_get_args();
		if ( count($tmp) > 1 )
		{
			$this->_query[$name_var] = '';
			$ds = '';
			$name_var = array_shift($tmp);
			$traslate = array(self::DS => self::ESCAPE_DS . self::DS);
			foreach($tmp as $p)
			{
				$this->_query[$name_var] .= $ds . strtr($p,$traslate);
				$ds = self::DS;
			}
		}
		else
		{
			$this->_query[$name_var] = $n0;
		}
		return $this;
	}
	public function __toString()
	{
		return $this->href();
	}
	public function href($arg_separator = '&')
	{
		if(!is_string($this->_string['query']))
		{
			$this->_string['query'] = '?'.http_build_query($this->_query,'',$arg_separator);
		}
		return implode('',$this->_string);
	}
	public function _($arg_separator = '&')
	{
		return $this->href($arg_separator);
	}
	public static function newUrl($host='')
	{
		return new self($host);
	}
	public static function newPath($Path)
	{
		return self::newUrl()->Path($Path);
	}
	public static function newQuery($query,$delete = array())
	{
		return self::newUrl()->Query($query,$delete);
	}
	public static function newArgument($name,$value)
	{
		return self::newUrl()->setArgument($name,$value);
	}
	public static function addArgument($name,$value)
	{
		return self::newUrl()->Query($_GET)->setArgument($name,$value);
	}
	public static function newController()
	{
		$vars = func_get_args();
		return call_user_func_array(array(self::newUrl(),'setController'),$vars);
	}
	/*public static function getController($name)
	{
		if(isset($_GET[$name]))
		{
			return explode(self::DS,$_GET[$name]);
		}
		return array();
	}*/
	/**
	 * Este metodo retorna el nombre del controlador y los demas como argumentos muy util y retorna false si no se encuentra
	 * URL::getController(string $name,ref & $pieces)
	 * @param string $name nombre del contolador
	 * @param mixed & $argumentos by ref variable del tipo array que retorna los argumentos
	 * @param mixed & $controller_default el valor por defecto al no encontrarse la variable
	 * @return string|bool
	 */
	public static function getController($name, & $arguments = array(),$controller_default = false)
	{
		if(isset($_GET[$name]))
		{
			$arguments = system::explode(self::DS,$_GET[$name],self::ESCAPE_DS);
			return array_shift($arguments);
		}else{$arguments = array();}
		return $controller_default;
	}
	public static function replaceController($name, $search,$other)
	{
		$vars = func_get_args();
		$name = array_shift($vars);
		$search = array_shift($vars);
		$get_arguments = system::explode(self::DS,$_GET[$name],self::ESCAPE_DS);
		$key = array_search($search ,$get_arguments,true);
		if($key !== false)
		{
			//$get_arguments = array_splice($get_arguments,0,$key)
			$get = array_merge(array_slice($get_arguments,0,$key),$vars);
			//$get = array_slice($get_arguments,0,$key);
			array_unshift($get,$name);
		}
		return call_user_func_array(array(self::newUrl()->Query($_GET),"setController"),$get );
	}
	public static function newReplaceController($name, $search,$other)
	{
		$vars = func_get_args();
		$name = array_shift($vars);
		$search = array_shift($vars);
		$get_arguments = system::explode(self::DS,$_GET[$name],self::ESCAPE_DS);
		$key = array_search($search ,$get_arguments,true);
		if($key !== false)
		{
			//$get_arguments = array_splice($get_arguments,0,$key)
			$get = array_merge(array_slice($get_arguments,0,$key),$vars);
			//$get = array_slice($get_arguments,0,$key);
			array_unshift($get,$name);
		}
		return call_user_func_array(array(self::newUrl(),"setController"),$get );
	}
}